package ch3.Singleton;

/**
 * 基于双重检查锁定的错误单例模式实现
 * 在这种错误的写法中，若仅考虑可见性的话，看起来是没有问题的
 * 但是考虑到重排序的存在，一个线程在执行操作1的时候可能发现instance不为null，于是该线程就直接将该instance返回，但是该instance变量锁引用
 * 的实例可能是还未初始化的
 *
 * 重排序：操作3可以拆分成3条子操作，其中子操作2和子操作3交换位置，会导致上述情况发生
 * 子操作2：初始化该实例对象
 * 子操作3：将该实例对象的引用赋值给instance变量
 */

public class IncorrectDCLSingleton {
    private static IncorrectDCLSingleton instance = null;

    private IncorrectDCLSingleton() {}

    // 创建并返回该类的唯一实例
    public static IncorrectDCLSingleton getInstance() {
        if (null == instance) {   // 操作1
            synchronized (IncorrectDCLSingleton.class) {
                if (null == instance) {  // 操作2
                    instance = new IncorrectDCLSingleton();  // 操作3
                }
            }
        }
        return instance;
    }
}
